using System;
using System.Collections.Generic;
using System.Text;
using System.Reflection;
using System.Collections.Specialized;


namespace DAL
{
    public static class Reflector
    {
        public static List<T> GetTypedFields<T>(object parent)
        {
            if (parent == null)
                return null;

            Type type = parent.GetType();

            List<T> ret = new List<T>();


            foreach (FieldInfo f in type.GetFields())
            {
                try
                {

                    object val = f.GetValue(parent);
                    if (val is T)
                        ret.Add((T)val);
                }
                catch { }

            }



            return ret;
        }




        public static List<FieldWithAttributesInfo<TAttribute>> GetFieldsByAttribute<TAttribute>(Type obj,Type attr)
        {
           
            //Type type = parent.GetType();
            List<FieldWithAttributesInfo<TAttribute>> ret = new List<FieldWithAttributesInfo<TAttribute>>();

            
            foreach (FieldInfo f in obj.GetFields())
            {
                try
                {

                    object[] attributes = f.GetCustomAttributes(attr, true);
                    if (attributes != null && attributes.Length>0)
                    {
                        FieldWithAttributesInfo<TAttribute> finfo = new FieldWithAttributesInfo<TAttribute>();
                        finfo.FieldInfo = f;
                        finfo.Attribute = (TAttribute)attributes[0];
                        ret.Add(finfo);
                    }
                }
                catch (Exception exp)
                {
                    int i = 0;
                }

            }


            

            return ret;
        }


        //public static Attribute GetClassAttribute(object obj,Type attr)
        //{

        //    if (obj == null)
        //        return null;

        //    Type type = obj.GetType();

        //    object [] ret =  type.GetCustomAttributes(attr,true);
        //    if (ret != null)
        //    {
        //        return (Attribute) ret[0];
        //    }
        //    return null;
        //}

        public static List<TAttribute> GetClassAttributes<TAttribute>(object obj)
        {
            List<TAttribute> ret = new List<TAttribute>();
            Type type = obj.GetType();
            object [] attr = type.GetCustomAttributes(typeof(TAttribute) ,true);

            if (attr != null)
            {
                foreach (TAttribute t in attr)
                {
                    ret.Add(t);

                }
            }
            return ret;
        }
        public static TAttribute GetClassAttribute<TAttribute>(object obj)
        {
            TAttribute ret = default(TAttribute);
            List<TAttribute> attr = GetClassAttributes<TAttribute>(obj);
            if(attr.Count>0)
                ret = attr[0];
            return ret;
        }


        public static TEntity EntityFromParams<TEntity>(IOrderedDictionary dic)
        {
            TEntity obj = Activator.CreateInstance<TEntity>();

            Type t = typeof(TEntity);
            foreach (string par in dic.Keys)
            {
                try
                {
                    PropertyInfo pinfo = t.GetProperty(par);
                    pinfo.SetValue(obj, dic[par], null);
                }
                catch { }
            }

            return obj;

        }

        public static object EntityFromParams(Type t , IOrderedDictionary dic)
        {
            object obj = Activator.CreateInstance(t);

           
            foreach (string par in dic.Keys)
            {
                try
                {
                    PropertyInfo pinfo = t.GetProperty(par);
                    pinfo.SetValue(obj, dic[par], null);
                }
                catch { }
            }

            return obj;

        }

        public static Type GetSPType<Entity, sp>(Table<Entity> Table, string Prefix, string Postfix , string Separator)
       {
           try
           {
               object spt = GetClassAttribute<sp>(Table);
               if (spt == null)
               {
                   Type t = Table.GetType();
                   string type = string.Format("{0}.{1}{4}{2}{4}{3}, {5}" , t.Namespace , Prefix , Table.TableName , Postfix ,Separator , t.Assembly.FullName);
                   return Type.GetType(type);


               }
               else
               {
                   return ((spType)spt).Type;
               }

           }
           catch { }

           return null;
       }

    }
}
